﻿using HtmlAgilityPack;
using StockDataBase.models;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using 股票数据;

namespace StockDataBase.Html
{
    public class HtmlParse
    {
        private HtmlParse()
        {

        }
        private static HtmlParse ins = new HtmlParse();
        public static HtmlParse Instance
        {
            get
            {
                return ins;
            }
        }

        private string name_replace(string txt)
        {
            txt = txt.Replace("&nbsp;", "");
            txt = txt.Replace("(", "_");
            txt = txt.Replace(")", "_");
            txt = txt.Replace(":", "_");
            txt = txt.Replace("、", "_");
            txt = txt.Replace(".", "_");
            return txt;
        }


        private void insert(object obj)
        {
            if (obj is NormalReport)
            {
                var item = obj as NormalReport;
                Utils.DB_Client.Delete<NormalReport>(new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });
                Utils.DB_Client.Insert<NormalReport>(item);
            }
            else if (obj is SecurityReport)
            {
                var item = obj as SecurityReport;
                Utils.DB_Client.Delete<SecurityReport>(new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });
                Utils.DB_Client.Insert<SecurityReport>(item);
            }
            else if (obj is BankReport)
            {
                var item = obj as BankReport;
                Utils.DB_Client.Delete<BankReport>(new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });
                Utils.DB_Client.Insert<BankReport>(item);
            }
            else if (obj is InsuranceReport)
            {
                var item = obj as InsuranceReport;
                Utils.DB_Client.Delete<InsuranceReport>(new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });
                Utils.DB_Client.Insert<InsuranceReport>(item);
            }


            /*
            string sql = "select * from NormalReport where ( [m001_stockId] = '{0}' and [m002_time]='{1}'  )";
            if(obj is NormalReport)
            {
                var item = obj as NormalReport;
                sql = string.Format(sql, item.m001_stockId, item.m002_time);
                var res = Utils.DB_Client.Select<NormalReport>(sql);
                if (res.Count == 0)
                {
                    Utils.DB_Client.Insert<NormalReport>(item);
                }
                else
                {
                    Utils.DB_Client.Update<NormalReport>(item, new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });

                }
            }
            else if (obj is BankReport )
            {
                var item = obj as BankReport;
                sql = string.Format(sql, item.m001_stockId, item.m002_time);
                var res = Utils.DB_Client.Select<BankReport>(sql);
                if (res.Count == 0)
                {
                    Utils.DB_Client.Insert<BankReport>(item);
                }
                else
                {
                    Utils.DB_Client.Update<BankReport>(item, new { m001_stockId = item.m001_stockId, m002_time = item.m002_time });

                }
            }

            */

        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns></returns>
        private Type get_report_type(DataTable dt)
        {
            string s = "";
            if ((s = dt.Rows[2][0].ToString()) == name_replace("存放同业和其它金融机构款项(元)"))
            {
                return typeof(BankReport);
            }
            else if (( s = dt.Rows[2][0].ToString()) == name_replace("其中:客户资金存款(元)"))
            {
                return typeof(SecurityReport);
            }
            else if ( (s = dt.Rows[2][0].ToString()) == name_replace("应收账款(元)"))
            {
                return typeof(NormalReport);
            }
            else if ((s = dt.Rows[2][0].ToString()) == name_replace("拆出资金(元)"))
            {
                return typeof(InsuranceReport);
            }
            else
            {
                throw new Exception("可能出现新的报表种类");
            }
            
        }


        /// <summary>
        /// 分析深圳和上海的所有三张表
        /// </summary>
        private void parse_sz_sh()
        {
            Utils.DB_Client.CreateTable(typeof(BankReport));
            Utils.DB_Client.CreateTable(typeof(NormalReport));
            Utils.DB_Client.CreateTable(typeof(SecurityReport));
            Utils.DB_Client.CreateTable(typeof(InsuranceReport));

            var dinfo = new DirectoryInfo(Utils.REPORT_PATH );

            MainWindow.Instance.Dispatcher.Invoke(() => {
                MainWindow.Instance.pb.Maximum = dinfo.GetFiles().Length;
                MainWindow.Instance.pb.Value = 0;
            });
            

            foreach (var file in dinfo.GetFiles())
            {
                HtmlDocument htmlDocument = new HtmlDocument();
                htmlDocument.Load(file.FullName, Encoding.UTF8);//加载HTML字符串，如果是文件可以用htmlDocument.Load方法加载
                var table = htmlDocument.GetElementbyId("BBMX_table");

                //创建一个数据表
                var dt = new DataTable();

                //数据表创建列
                foreach (HtmlNode node in table.ChildNodes)
                {
                    var list = new List<string>();
                    foreach (var col in node.ChildNodes)
                    {
                        var txt = col.InnerText;
                        txt = name_replace(txt);
                        list.Add(txt);
                    }
                    if (list.Count != 0)
                    {
                        foreach (var li in list)
                        {
                            dt.Columns.Add(li, typeof(string));
                        }
                        //LogUtils.Print(">>>>>> 列数目" + list.Count);
                        break;
                    }
                }
                //数据表增加行
                foreach (HtmlNode node in table.ChildNodes)
                {
                    var line = "";
                    List<string> row = new List<string>();
                    foreach (var col in node.ChildNodes)
                    {
                        var txt = col.InnerText;
                        txt = name_replace(txt);
                        row.Add(txt);
                        line += (txt + "  ");
                    }
                    if (row.Count != 0)
                    {
                        dt.Rows.Add(row.ToArray());
                        //LogUtils.Print(">>>>>>" + row.Count);
                        //LogUtils.Print(line);
                    }
                }


                for (int i = 1; i < dt.Columns.Count; i++)
                {
                    Type t = null;
                    try
                    {
                        t = get_report_type(dt);
                    }
                    catch (Exception ex)
                    {
                        string info = ex.Message + "ID = " + file.Name;
                        App.Current.Dispatcher.Invoke(()=>{
                            MessageBox.Show(info);
                        });

                        break;
                    }
                    var br = (ReportBase)t.GetConstructor(System.Type.EmptyTypes).Invoke(null);
                    br.SetStockId(  file.Name.Replace(".html", "") );
                    br.SetTime(   dt.Columns[i].ColumnName ) ;

                    var pi_list = t.GetProperties();
                    for (int x = 2; x < pi_list.Length; x++)
                    {
                        bool find = false ;
                        //到行里面找到这个属性
                        for (int j = 1; j < dt.Rows.Count; j++)
                        {
                            if (dt.Rows[j][0].ToString() == pi_list[x].Name.Substring(5, pi_list[x].Name.Length - 5))
                            {
                                //LogUtils.Print("找到了 " + pi_list[x].Name);
                                pi_list[x].SetValue(br, dt.Rows[j][i]);
                                find = true;
                                break;
                            }
                        }
                        if(!find)
                        {
                            App.Current.Dispatcher.Invoke(() =>
                            {
                                MessageBox.Show("没找到 " + pi_list[x].Name);
                            });

                        }
                    }
                    insert(br);
                }



                /*

                //-----------------------------------------------------------------------------
                if( get_report_type(dt) == typeof( BankReport ) )
                {
                    for (int i = 1; i < dt.Columns.Count; i++)
                    {
                        var br = new BankReport();
                        br.m001_stockId = file.Name.Replace(".html", "");
                        br.m002_time = dt.Columns[i].ColumnName;

                        var pi_list = typeof(BankReport).GetProperties();
                        for (int x = 2; x < pi_list.Length; x++)
                        {
                            //到行里面找到这个属性
                            for (int j = 1; j < dt.Rows.Count; j++)
                            {
                                if (dt.Rows[j][0].ToString() == pi_list[x].Name.Substring(5, pi_list[x].Name.Length - 5))
                                {
                                    //LogUtils.Print("找到了 " + pi_list[x].Name);
                                    pi_list[x].SetValue(br, dt.Rows[j][i]);
                                    break;
                                }
                            }
                        }
                        insert(br);
                    }
                }
                else if (get_report_type(dt) == typeof(NormalReport))
                {
                    for (int i = 1; i < dt.Columns.Count; i++)
                    {
                        var br = new NormalReport();
                        br.m001_stockId = file.Name.Replace(".html", "");
                        br.m002_time = dt.Columns[i].ColumnName;

                        var pi_list = typeof(NormalReport).GetProperties();
                        for (int x = 2; x < pi_list.Length; x++)
                        {
                            //到行里面找到这个属性
                            for (int j = 1; j < dt.Rows.Count; j++)
                            {
                                if (dt.Rows[j][0].ToString() == pi_list[x].Name.Substring(5, pi_list[x].Name.Length - 5))
                                {
                                    //LogUtils.Print("找到了 " + pi_list[x].Name);
                                    pi_list[x].SetValue(br, dt.Rows[j][i]);
                                    break;
                                }
                            }
                        }
                        insert(br);
                    }
                }
                else if (get_report_type(dt) == typeof(SecurityReport))
                {

                }
                else
                {

                }
     
                */
                LogUtils.Print(file + " 分析成功");
                MainWindow.Instance.Dispatcher.Invoke(() =>
                {
                    MainWindow.Instance.pb.Value++;
                });

            }

        }




        public  void ParseHtmlToDataBase()
        {
            parse_sz_sh();
        }


    }
}
